package com.demo.juc.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @Author: jxm
 * @Description: 自定义自旋锁
 * @Date: 2022/4/2 10:11
 * @Version: 1.0
 */
public class SpinLockTest {

    /**
     * compare的使用：CAS有3个操作数，内存值V，旧的预期值A，要修改的新值B。当且仅当预期值A和内存值V相同时，将内存值V修改为B，否则什么都不做。
     */

    //原子引用
    AtomicReference<Thread> reference = new AtomicReference<>();//内存值是默认是null

    public void myLock(){
        Thread thread = Thread.currentThread();
        System.out.println(Thread.currentThread().getName()+"\t come in .........");
        //第一次进来内存值就是null
        while (!reference.compareAndSet(null,thread)){ //加入A线程先进来，更改了内存值；当B线下进入则不为空，B线程进入循环
            System.out.println(Thread.currentThread().getName()+"\t 进入循环while .........");
        }
    }

    public void  myUnLock(){
        Thread thread = Thread.currentThread();
        reference.compareAndSet(thread,null);
        System.out.println(Thread.currentThread().getName()+"\t invoked myUnLock");
    }

    public static void main(String[] args){

        SpinLockTest jucTest = new SpinLockTest();

        new Thread(()->{
            jucTest.myLock();
            try {
//                TimeUnit.SECONDS.sleep(10);
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                jucTest.myUnLock();
            }

        },"A").start();


        new Thread(()->{
            jucTest.myLock();
            try {
                TimeUnit.SECONDS.sleep(10);
//                Thread.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                jucTest.myUnLock();
            }
        },"B").start();

//        new Thread(()->{
//            jucTest.myLock();
//            try {
////                TimeUnit.SECONDS.sleep(2);
//                Thread.sleep(10);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }finally {
//                jucTest.myUnLock();
//            }
//        },"C").start();


    }


}
